/**
 * @file thread_utils.h
 * @brief 线程工具函数
 * @version 2.0
 * @date 2023-05-20
 */

#ifndef THREAD_UTILS_H
#define THREAD_UTILS_H

#include <pthread.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

// 线程函数类型定义
typedef void *(*ThreadFunc)(void *);

/**
 * @brief 创建并启动线程
 * 
 * @param thread 线程ID指针
 * @param func 线程函数
 * @param arg 线程函数参数
 * @param name 线程名称（调试用）
 * @return int 成功返回0，失败返回非0
 */
int create_thread(pthread_t *thread, ThreadFunc func, void *arg, const char *name);

/**
 * @brief 等待线程结束
 * 
 * @param thread 线程ID
 * @param result 线程返回值指针
 * @return int 成功返回0，失败返回非0
 */
int join_thread(pthread_t thread, void **result);

/**
 * @brief 取消线程
 * 
 * @param thread 线程ID
 * @return int 成功返回0，失败返回非0
 */
int cancel_thread(pthread_t thread);

/**
 * @brief 设置线程的取消状态
 * 
 * @param state 0：禁用取消，非0：启用取消
 * @return int 成功返回0，失败返回非0
 */
int set_thread_cancel_state(int state);

/**
 * @brief 设置线程的取消类型
 * 
 * @param type 0：延迟取消，非0：异步取消
 * @return int 成功返回0，失败返回非0
 */
int set_thread_cancel_type(int type);

/**
 * @brief 创建互斥锁
 * 
 * @param mutex 互斥锁指针
 * @return int 成功返回0，失败返回非0
 */
int create_mutex(pthread_mutex_t *mutex);

/**
 * @brief 销毁互斥锁
 * 
 * @param mutex 互斥锁指针
 * @return int 成功返回0，失败返回非0
 */
int destroy_mutex(pthread_mutex_t *mutex);

/**
 * @brief 锁定互斥锁
 * 
 * @param mutex 互斥锁指针
 * @return int 成功返回0，失败返回非0
 */
int lock_mutex(pthread_mutex_t *mutex);

/**
 * @brief 尝试锁定互斥锁
 * 
 * @param mutex 互斥锁指针
 * @return int 成功返回0，失败返回非0
 */
int try_lock_mutex(pthread_mutex_t *mutex);

/**
 * @brief 解锁互斥锁
 * 
 * @param mutex 互斥锁指针
 * @return int 成功返回0，失败返回非0
 */
int unlock_mutex(pthread_mutex_t *mutex);

/**
 * @brief 创建条件变量
 * 
 * @param cond 条件变量指针
 * @return int 成功返回0，失败返回非0
 */
int create_cond(pthread_cond_t *cond);

/**
 * @brief 销毁条件变量
 * 
 * @param cond 条件变量指针
 * @return int 成功返回0，失败返回非0
 */
int destroy_cond(pthread_cond_t *cond);

/**
 * @brief 等待条件变量
 * 
 * @param cond 条件变量指针
 * @param mutex 互斥锁指针
 * @return int 成功返回0，失败返回非0
 */
int wait_cond(pthread_cond_t *cond, pthread_mutex_t *mutex);

/**
 * @brief 等待条件变量（带超时）
 * 
 * @param cond 条件变量指针
 * @param mutex 互斥锁指针
 * @param timeout_ms 超时时间（毫秒）
 * @return int 成功返回0，超时返回ETIMEDOUT，失败返回其他非0值
 */
int wait_cond_timeout(pthread_cond_t *cond, pthread_mutex_t *mutex, long timeout_ms);

/**
 * @brief 唤醒一个等待条件变量的线程
 * 
 * @param cond 条件变量指针
 * @return int 成功返回0，失败返回非0
 */
int signal_cond(pthread_cond_t *cond);

/**
 * @brief 唤醒所有等待条件变量的线程
 * 
 * @param cond 条件变量指针
 * @return int 成功返回0，失败返回非0
 */
int broadcast_cond(pthread_cond_t *cond);

/**
 * @brief 线程休眠
 * 
 * @param ms 休眠时间（毫秒）
 */
void thread_sleep(unsigned long ms);

/**
 * @brief 设置当前线程的名称
 * 
 * @param name 线程名称
 * @return int 成功返回0，失败返回非0
 */
int set_thread_name(const char *name);

// 以下是整合自global_mutex.h的内容

// 互斥锁类型
typedef enum {
    MUTEX_ICE_THICKNESS = 0,  // 保护覆冰厚度相关变量
    MUTEX_FUSION_DATA,        // 保护融合数据
    MUTEX_CONFIG,             // 保护配置数据
    MUTEX_VISUAL_DATA,        // 保护视觉数据
    MUTEX_STEREO_DATA,        // 保护立体视觉数据
    MUTEX_SENSOR_DATA,        // 保护传感器数据
    MUTEX_FILE_ACCESS,        // 保护文件访问
    MUTEX_DATA_ACCESS,        // 保护通用数据访问
    MUTEX_NETWORK_ACCESS,     // 保护网络访问
    MUTEX_COUNT               // 互斥锁总数，必须放在最后
} MutexType;

/**
 * @brief 初始化全局互斥锁系统
 * 
 * @return int 成功返回0，失败返回非0
 */
int init_global_mutex(void);

/**
 * @brief 清理全局互斥锁系统
 */
void cleanup_global_mutex(void);

/**
 * @brief 锁定指定类型的互斥锁
 * 
 * @param type 互斥锁类型
 * @return int 成功返回0，失败返回非0
 */
int lock_global_mutex(MutexType type);

/**
 * @brief 尝试锁定指定类型的互斥锁，非阻塞
 * 
 * @param type 互斥锁类型
 * @return int 成功锁定返回0，锁已被占用返回EBUSY，其他错误返回对应错误码
 */
int try_lock_global_mutex(MutexType type);

/**
 * @brief 解锁指定类型的互斥锁
 * 
 * @param type 互斥锁类型
 * @return int 成功返回0，失败返回非0
 */
int unlock_global_mutex(MutexType type);

/**
 * @brief 安全的设置当前覆冰厚度
 * 
 * @param thickness 覆冰厚度值(mm)
 */
void set_ice_thickness_safe(float thickness);

/**
 * @brief 安全的获取当前覆冰厚度
 * 
 * @return float 当前覆冰厚度值(mm)
 */
float get_ice_thickness_safe(void);

/**
 * @brief 安全的设置上一次覆冰厚度
 * 
 * @param thickness 上一次覆冰厚度值(mm)
 */
void set_previous_ice_thickness_safe(float thickness);

/**
 * @brief 安全的获取上一次覆冰厚度
 * 
 * @return float 上一次覆冰厚度值(mm)
 */
float get_previous_ice_thickness_safe(void);

/**
 * @brief 安全地更新当前和上一次覆冰厚度（原子操作）
 * 
 * @param current_thickness 当前覆冰厚度值(mm)
 */
void update_ice_thickness_safe(float current_thickness);

#ifdef __cplusplus
}
#endif

#endif /* THREAD_UTILS_H */ 